package cs6238.common;

import java.nio.ByteBuffer;
import java.util.UUID;


/**
 * Used for storing info on delegated files, can be read to/from disk
 */
public class DelegateEntry {

	private UUID _fileId;
	private String _owningHost;
	private String _delegatedHost;
	private byte[] _signature;
	private long _expiration;
	private boolean _star;
	
	public DelegateEntry(String csv){
		String[] parts = csv.split(",");
		_owningHost = parts[0];
		_delegatedHost = parts[1];
		_expiration = Long.parseLong(parts[2]);
		_star = Boolean.parseBoolean(parts[3]);
		_fileId = UUID.fromString(parts[4]);
		_signature = ByteArray.fromHexString(parts[5]);
	}
	
	public DelegateEntry(UUID fileId, String owningHost, String delegatedHost, long expiration, boolean star){
		Guard.NoNullArguments(fileId, owningHost, delegatedHost);
		_fileId = fileId;
		_owningHost = owningHost;
		_delegatedHost = delegatedHost;
		_expiration = expiration;
		_star = star;
		_signature = new byte[0];
	}
	
	public DelegateEntry(ByteBuffer bb) {
		long mostSig = bb.getLong();
		long leastSig = bb.getLong();
		_fileId = new UUID(mostSig, leastSig);
		_owningHost = ByteArray.readString(bb);
		_delegatedHost = ByteArray.readString(bb);
		int signatureLength = bb.getInt();
		_signature = new byte[signatureLength];
		bb.get(_signature);
		_expiration = bb.getLong();
		_star = (bb.get() == 1);
	}

	public static String toCsvColumns() {
		return "owningHost,delegatedHost,expiration,allFiles,fileId,signature";
	}

	public String toCSV() {
		StringBuilder sb = new StringBuilder();
		sb.append(_owningHost);				sb.append(",");
		sb.append(_delegatedHost);			sb.append(",");
		sb.append(_expiration);				sb.append(",");
		sb.append(_star);					sb.append(",");
		sb.append(_fileId.toString());		sb.append(",");
		String sig = ByteArray.toHexString(_signature);
		sb.append(sig);
		
		return sb.toString();
	}

	
	public UUID getFileId(){
		return _fileId;
	}
	
	public String getOwningHost(){
		return _owningHost;
	}
	
	public String getDelegatedHost(){
		return _delegatedHost;
	}

	public long getExpiration(){
		return _expiration;
	}
	
	public boolean getStar(){
		return _star;
	}
	
	public byte[] getSignature(){
		return _signature;
	}
	
	public boolean hasExpired(){
		return System.currentTimeMillis() > _expiration;
	}

	public byte[] serialize() {
		byte[] owningHost = ByteArray.writeString(_owningHost);
		byte[] delegatedHost = ByteArray.writeString(_delegatedHost);
		
		ByteBuffer bb = ByteBuffer.allocate(16 + owningHost.length + delegatedHost.length + 4 + _signature.length +  8 + 1);
		bb.putLong(_fileId.getMostSignificantBits());
		bb.putLong(_fileId.getLeastSignificantBits());
		bb.put(owningHost);
		bb.put(delegatedHost);
		bb.putInt(_signature.length);
		bb.put(_signature);
		bb.putLong(_expiration);
		bb.put((byte)(_star ? 1 : 0));
		return bb.array();
	}

	public byte[] serializeWithoutSignature() {
		byte[] goodSignature = _signature;
		_signature = new byte[0];
		
		byte[] result = serialize();
		_signature = goodSignature;
		
		return result;
	}

	public void setSignature(byte[] signature) {
		_signature = signature;
	}
}
